package com.ethink.warehouse.facade.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ethink.framework.common.constant.CommonRespCode;
import com.ethink.framework.common.exception.BusinessException;
import com.ethink.warehouse.api.LogisticsTransferOrderFacade;
import com.ethink.warehouse.api.enums.LogisticsTraceDetailOrderTypeEnum;
import com.ethink.warehouse.api.enums.LogisticsTransferOrderOrderStatusEnum;
import com.ethink.warehouse.api.enums.SubjectEnum;
import com.ethink.warehouse.api.info.LogisticsTransferDetailOrderInfo;
import com.ethink.warehouse.api.info.LogisticsTransferOrderInfo;
import com.ethink.warehouse.api.request.*;
import com.ethink.warehouse.api.response.LogisticsTransferOrderAddResponse;
import com.ethink.warehouse.api.response.LogisticsTransferOrderDetailResponse;
import com.ethink.warehouse.api.response.LogisticsTransferOrderQueryItemModeResponse;
import com.ethink.warehouse.api.response.LogisticsTransferOrderQueryResponse;
import com.ethink.warehouse.common.mapper.LogisticsTraceApplyOrderMapper;
import com.ethink.warehouse.common.mapper.LogisticsTransferOrderMapper;
import com.ethink.warehouse.manager.LogisticsTraceDetailManager;
import com.ethink.warehouse.manager.MateInventoryManager;
import com.ethink.warehouse.service.LogisticsTraceDetailOrderService;
import com.ethink.warehouse.service.LogisticsTransferOrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 物流调拨单 Facade接口实现
 *
 * @author default
 * @date 2022-11-10
 */
@RestController
@Slf4j
@RequestMapping("warehouse-service/facade/v1/logisticsTransferOrder")
public class LogisticsTransferOrderFacadeImpl implements LogisticsTransferOrderFacade {

    @Autowired
    private LogisticsTransferOrderService logisticsTransferOrderService;

    @Autowired
    private LogisticsTraceDetailOrderService logisticsTraceDetailOrderService;

    @Autowired
    private MateInventoryManager mateInventoryManager;

    @Autowired
    private LogisticsTraceDetailManager logisticsTraceDetailManager;

    @Autowired
    private LogisticsTraceApplyOrderMapper logisticsTraceApplyOrderMapper;

    @Autowired
    private LogisticsTransferOrderMapper logisticsTransferOrderMapper;

    @Override
    public Page<LogisticsTransferOrderQueryResponse> queryLogisticsTransferOrder(LogisticsTransferOrderQueryRequest request) {
        return logisticsTransferOrderService.queryLogisticsTransferOrder(request);
    }

    @Override
    public LogisticsTransferOrderQueryResponse queryLogisticsTransferOrderSum(LogisticsTransferOrderQueryRequest request) {
        return logisticsTransferOrderMapper.queryLogisticsTransferOrderSum(request);
    }

    @Override
    public LogisticsTransferOrderDetailResponse getLogisticsTransferOrderById(Long logisticsTransferOrderId) {
        return logisticsTransferOrderService.getLogisticsTransferOrderById(logisticsTransferOrderId);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public LogisticsTransferOrderAddResponse addLogisticsTransferOrder(LogisticsTransferOrderAddRequest request) {
        LogisticsTransferOrderAddResponse response = logisticsTransferOrderService.addLogisticsTransferOrder(request);
        if (request.getAddType() == 2) {
            LogisticsTransferOrderInfo logisticsTransferOrderInfo = response.getLogisticsTransferOrderInfo();
            List<LogisticsTransferDetailOrderInfo> logisticsTransferDetailOrderInfoList = response.getLogisticsTransferDetailOrderInfoList();
            List<MateInventoryLockLogAddRequest> mateInventoryLockLogAddRequestList = new ArrayList<>();
            for (LogisticsTransferDetailOrderInfo detailOrderInfo : logisticsTransferDetailOrderInfoList) {
                MateInventoryLockLogAddRequest mateInventoryLockLogAddRequest = new MateInventoryLockLogAddRequest();
                mateInventoryLockLogAddRequest.setOrderType(LogisticsTraceDetailOrderTypeEnum.T2.getIntValue());
                mateInventoryLockLogAddRequest.setSourceOrderNo(logisticsTransferOrderInfo.getOrderNo());
                mateInventoryLockLogAddRequest.setSourceDetailOrderNo(detailOrderInfo.getDetailOrderNo());
                mateInventoryLockLogAddRequest.setSourceOrderType(SubjectEnum.T32.getCode());
                mateInventoryLockLogAddRequest.setSubject(SubjectEnum.T32.getCode());
                mateInventoryLockLogAddRequest.setMateInventoryId(detailOrderInfo.getMateInventoryId());
                mateInventoryLockLogAddRequest.setLockQty(detailOrderInfo.getQty());
                mateInventoryLockLogAddRequestList.add(mateInventoryLockLogAddRequest);
            }
            mateInventoryManager.lockMateInventory(mateInventoryLockLogAddRequestList);

            logisticsTraceDetailManager.dbCreateLogisticsTraceDetailOrder(response.getLogisticsTransferOrderInfo(), response.getLogisticsTransferDetailOrderInfoList());
        }
        return response;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateLogisticsTransferOrder(LogisticsTransferOrderUpdateRequest request) {
        logisticsTransferOrderService.updateLogisticsTransferOrder(request);
        if (request.getUpdateType() == 2) {
            LogisticsTransferOrderDetailResponse response = logisticsTransferOrderService.getLogisticsTransferOrderById(request.getId());
            LogisticsTransferOrderInfo logisticsTransferOrderInfo = response.getLogisticsTransferOrderInfo();
            List<LogisticsTransferDetailOrderInfo> logisticsTransferDetailOrderInfoList = response.getLogisticsTransferDetailOrderInfoList();
            List<MateInventoryLockLogAddRequest> mateInventoryLockLogAddRequestList = new ArrayList<>();
            for (LogisticsTransferDetailOrderInfo detailOrderInfo : logisticsTransferDetailOrderInfoList) {
                MateInventoryLockLogAddRequest mateInventoryLockLogAddRequest = new MateInventoryLockLogAddRequest();
                mateInventoryLockLogAddRequest.setOrderType(LogisticsTraceDetailOrderTypeEnum.T2.getIntValue());
                mateInventoryLockLogAddRequest.setSourceOrderNo(logisticsTransferOrderInfo.getOrderNo());
                mateInventoryLockLogAddRequest.setSourceDetailOrderNo(detailOrderInfo.getDetailOrderNo());
                mateInventoryLockLogAddRequest.setSourceOrderType(SubjectEnum.T32.getCode());
                mateInventoryLockLogAddRequest.setSubject(SubjectEnum.T32.getCode());
                mateInventoryLockLogAddRequest.setMateInventoryId(detailOrderInfo.getMateInventoryId());
                mateInventoryLockLogAddRequest.setLockQty(detailOrderInfo.getQty());
                mateInventoryLockLogAddRequestList.add(mateInventoryLockLogAddRequest);
            }
            mateInventoryManager.lockMateInventory(mateInventoryLockLogAddRequestList);

            logisticsTraceDetailManager.dbCreateLogisticsTraceDetailOrder(response.getLogisticsTransferOrderInfo(), response.getLogisticsTransferDetailOrderInfoList());
        }
    }

    @Override
    public void deleteLogisticsTransferOrder(Long logisticsTransferOrderId) {
        logisticsTransferOrderService.deleteLogisticsTransferOrder(logisticsTransferOrderId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void setLogisticsTransferOrderStatus(LogisticsTransferOrderSetStatusRequest request) {
        LogisticsTransferOrderDetailResponse response = logisticsTransferOrderService.getLogisticsTransferOrderById(request.getId());
        LogisticsTransferOrderInfo logisticsTransferOrderInfo = response.getLogisticsTransferOrderInfo();
        if (logisticsTransferOrderInfo.getOrderStatus().equals(request.getOrderStatus())) {
            throw  new BusinessException(CommonRespCode.PARAM_ERR, "状态未发生更新");
        }

        if (!LogisticsTransferOrderOrderStatusEnum.S2.eq(logisticsTransferOrderInfo.getOrderStatus())) {
            throw  new BusinessException(CommonRespCode.PARAM_ERR, "当前状态单据不能变更状态");
        }
        if(!LogisticsTransferOrderOrderStatusEnum.S3.eq(request.getOrderStatus()) && !LogisticsTransferOrderOrderStatusEnum.S1.eq(request.getOrderStatus())) {
            throw  new BusinessException(CommonRespCode.PARAM_ERR, "状态参数不合法");
        }
        logisticsTransferOrderService.setLogisticsTransferOrderStatus(request);

        List<LogisticsTransferDetailOrderInfo> logisticsTransferDetailOrderInfoList = response.getLogisticsTransferDetailOrderInfoList();
        if (LogisticsTransferOrderOrderStatusEnum.S1.eq(request.getOrderStatus())) {
            List<MateInventoryLockLogAddRequest> mateInventoryLockLogAddRequestList = new ArrayList<>();
            for (LogisticsTransferDetailOrderInfo detailOrderInfo : logisticsTransferDetailOrderInfoList) {
                MateInventoryLockLogAddRequest mateInventoryLockLogAddRequest = new MateInventoryLockLogAddRequest();
                mateInventoryLockLogAddRequest.setOrderType(LogisticsTraceDetailOrderTypeEnum.T2.getIntValue());
                mateInventoryLockLogAddRequest.setSourceOrderNo(logisticsTransferOrderInfo.getOrderNo());
                mateInventoryLockLogAddRequest.setSourceDetailOrderNo(detailOrderInfo.getDetailOrderNo());
                mateInventoryLockLogAddRequest.setSourceOrderType(SubjectEnum.T32.getCode());
                mateInventoryLockLogAddRequest.setSubject(SubjectEnum.T32.getCode());
                mateInventoryLockLogAddRequest.setMateInventoryId(detailOrderInfo.getMateInventoryId());
                mateInventoryLockLogAddRequest.setLockQty(detailOrderInfo.getQty());
                mateInventoryLockLogAddRequestList.add(mateInventoryLockLogAddRequest);
            }
            mateInventoryManager.releaseLockMateInventory(mateInventoryLockLogAddRequestList);
        }
        if (LogisticsTransferOrderOrderStatusEnum.S3.eq(request.getOrderStatus())) {
            logisticsTraceDetailManager.dbCreateLogisticsTraceDetailOrder(response.getLogisticsTransferOrderInfo(), response.getLogisticsTransferDetailOrderInfoList());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelLogisticsTransferOrder(Long logisticsTransferOrderId) {
        LogisticsTransferOrderDetailResponse response = logisticsTransferOrderService.getLogisticsTransferOrderById(logisticsTransferOrderId);
        LogisticsTransferOrderInfo logisticsTransferOrderInfo = response.getLogisticsTransferOrderInfo();
        if (LogisticsTransferOrderOrderStatusEnum.S4.eq(logisticsTransferOrderInfo.getOrderStatus())) {
            throw new BusinessException(CommonRespCode.SYSTEM_ERR, "当前状态下，物流调拨单不允许撤回！");
        }
        if (LogisticsTransferOrderOrderStatusEnum.S2.eq(logisticsTransferOrderInfo.getOrderStatus()) ||
                LogisticsTransferOrderOrderStatusEnum.S3.eq(logisticsTransferOrderInfo.getOrderStatus())) {
            LogisticsTraceApplyDeleteRequest request = new LogisticsTraceApplyDeleteRequest();
            request.setSourceOrderNo(logisticsTransferOrderInfo.getOrderNo());
            request.setSourceOrderType(SubjectEnum.T32.getCode());
            request.setSourceDetailOrderNoList(response.getLogisticsTransferDetailOrderInfoList().stream().map(LogisticsTransferDetailOrderInfo::getDetailOrderNo).collect(Collectors.toList()));
            int ct = logisticsTraceApplyOrderMapper.countTracing(request);
            if (ct > 0) {
                throw new BusinessException(CommonRespCode.SYSTEM_ERR, "当前有正在跟进物流单，不允许撤回");
            }
            logisticsTraceApplyOrderMapper.deleteApply(request);

            List<LogisticsTransferDetailOrderInfo> logisticsTransferDetailOrderInfoList = response.getLogisticsTransferDetailOrderInfoList();
            List<MateInventoryLockLogAddRequest> mateInventoryLockLogAddRequestList = new ArrayList<>();
            for (LogisticsTransferDetailOrderInfo detailOrderInfo : logisticsTransferDetailOrderInfoList) {
                MateInventoryLockLogAddRequest mateInventoryLockLogAddRequest = new MateInventoryLockLogAddRequest();
                mateInventoryLockLogAddRequest.setOrderType(LogisticsTraceDetailOrderTypeEnum.T2.getIntValue());
                mateInventoryLockLogAddRequest.setSourceOrderNo(logisticsTransferOrderInfo.getOrderNo());
                mateInventoryLockLogAddRequest.setSourceDetailOrderNo(detailOrderInfo.getDetailOrderNo());
                mateInventoryLockLogAddRequest.setSourceOrderType(SubjectEnum.T32.getCode());
                mateInventoryLockLogAddRequest.setSubject(SubjectEnum.T32.getCode());
                mateInventoryLockLogAddRequest.setMateInventoryId(detailOrderInfo.getMateInventoryId());
                mateInventoryLockLogAddRequest.setLockQty(detailOrderInfo.getQty());
                mateInventoryLockLogAddRequestList.add(mateInventoryLockLogAddRequest);
            }
            mateInventoryManager.releaseLockMateInventory(mateInventoryLockLogAddRequestList);
        }
        logisticsTransferOrderService.cancelLogisticsTransferOrder(logisticsTransferOrderId);
    }

    @Override
    public List<String> queryLogisticsTransferDetailOrderNosByOrderNos(List<String> orderNos) {
        return logisticsTransferOrderService.queryLogisticsTransferDetailOrderNosByOrderNos(orderNos);
    }

    @Override
    public void updateLogisticsTransferOrderStatus(List<String> request) {
        logisticsTransferOrderService.updateLogisticsTransferOrderStatus(request);
    }

    /**
     * 货品模式分页查询
     *
     * @param request
     * @return
     */
    @Override
    public Page<LogisticsTransferOrderQueryItemModeResponse> queryItemModeLogisticsTransferOrder(LogisticsTransferOrderQueryItemModeRequest request) {
        return logisticsTransferOrderService.queryItemModeLogisticsTransferOrder(request);
    }
}